package org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.filter;

import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelFlowAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.advanced.HandleChannelTypeAdvanced;
import org.framework.lazy.cloud.network.heartbeat.common.filter.DebugChannelInitializer;
import org.framework.lazy.cloud.network.heartbeat.server.netty.proxy.socks.handler.NettySocksServerProxyClientVisitorHandler;
import org.wu.framework.spring.utils.SpringContextHolder;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class NettySocksServerProxyClientVisitorFilter extends DebugChannelInitializer<SocketChannel> {


    /**
     * This method will be called once the {@link Channel} was registered. After the method returns this instance
     * will be removed from the {@link ChannelPipeline} of the {@link Channel}.
     *
     * @param ch the {@link Channel} which was registered.
     * @throws Exception is thrown if an error occurs. In that case it will be handled by
     *                   {@link #exceptionCaught(ChannelHandlerContext, Throwable)} which will by default connectionClose
     *                   the {@link Channel}.
     */
    @Override
    protected void initChannel0(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast(new ChannelDuplexHandler());

        List<HandleChannelTypeAdvanced> handleChannelTypeAdvancedList = new ArrayList<>(SpringContextHolder.getApplicationContext().getBeansOfType(HandleChannelTypeAdvanced.class).values());

        pipeline.addLast(new NettySocksServerProxyClientVisitorHandler(new ChannelTypeAdapter(handleChannelTypeAdvancedList)));
    }
}